﻿//----------------------------------------------------------------
// Desc: 
// Edit: ShowLong, http://blog.csdn.net/showlong
//
// Date Created: 2010-06-20
//
// Update Date : 
//
// Copyright (c) Fuel4D (http://www.fuel4d.com), All rights reserved.
//
//----------------------------------------------------------------
#pragma once


class IFCamera : public IFService
{
protected:
    explicit IFCamera()
        :IFService(0)
    {}

public:
    // 取得眼睛位置
    virtual const FVECTOR3* const GetEye() = 0;
    // 取得眼睛所看位置
    virtual const FVECTOR3* const GetLookAt() = 0;
    // 取得上方向
    virtual const FVECTOR3* const GetUp() = 0;
    // 取得观察方向
    virtual const FVECTOR3* const GetView() = 0;
    // 取得右方向
    virtual const FVECTOR3* const GetRight() = 0;
    // 取得观察矩阵
    virtual const FMATRIX* const GetViewMatrix() = 0;
    // 取得世界矩阵
    virtual const FMATRIX* const GetWorldMatrix() = 0;
    // 取得广告牌矩阵
    virtual const FMATRIX* const GetBillboardMatrix() = 0;
    // 取得投影矩阵
    virtual const FMATRIX* const GetProjMatrix() = 0;
    // 取得三矩阵乘的结果 World * View * Projection
    virtual const FMATRIX* const GetWorldViewProjection() = 0;
    // 取得二矩阵乘的结果 World * View
    virtual const FMATRIX* const GetWorldView() = 0;
    // 获取地平线平面
    virtual const FPLANE* const GetGroundLevel() = 0;
    // 获取摄像机的广角度
    virtual float GetFOV() = 0;
    // 取得近平面值
    virtual float GetNear() = 0;
    // 取得远平面值
    virtual float GetFar() = 0;
    // 设置观察参数
    // .lookat 如果为0表示观察点不变
    virtual void SetViewParams(FVECTOR3* eye, FVECTOR3* lookat = 0, FVECTOR3* up = 0) = 0;
    // 设置投影参数
    virtual void SetProjParams(float fov, float fnear = 0.1f, float ffar = 1000.0f) = 0;
    // 通过当前摄像机设置生成视锥
    // .distance 如果小于等于0，按摄像机最远视距设置，否则按distance的值设置远平面距离
    virtual void BuildFrustum(FFRUSTUM* out, float distance = 0) = 0;
    // 根据当前屏幕2D选框生成视锥
    virtual void BuildFrustum_rect2d(FFRUSTUM* out, FVECTOR2* v0, FVECTOR2* v1, float distance = 0) = 0;
    // 通过鼠标生成拾取射线
    // x,y 屏幕坐标
    // origin 输出三难视点
    // dir 输出三难视线方向
    virtual void PickRay(float x, float y, FRAY* ray) = 0;
    // 通3D坐标取得2D的投影位置
    // .pos 三维坐标
    // .x,y 输出屏幕坐标
    // .return 是否转换成功
    virtual bool WorldToScreen(const FVECTOR3* pos, float& x, float& y) = 0;
    // 设置摄像机自动处理的观察模式，详见EF_CAMERA_VIEW_MODE说明
    // .viewmode 默认是eCVM_UserDefined
    virtual void SetViewMode(EF_CAMERA_VIEW_MODE viewmode) = 0;
    // 设置角色坐标
    // .height 角色的视点高度
    virtual void SetRolePosition(const FVECTOR3* pos, float height) = 0;
    // 提交world/view/projection参数给3D设备
    virtual void Commit(bool view = true, bool world = false, bool proj = false) = 0;
    // 取得某个3D坐标到摄像机的距离
    virtual float GetDistance(FVECTOR3* pos) = 0;
    // 取得某个3D坐标到摄像机的距离
    virtual float GetDistanceSq(FVECTOR3* pos) = 0;
    // 取得当前鼠标与地平线的交点
    virtual void GetCursorHorizon(FVECTOR3* pos) = 0;

    // 前后移动（远是正，近是负）
    // .dist 移动距离，单位：米
    virtual void MoveFar(float dist) = 0;
    // 左右移动（左移是正，右移是负）
    // .dist 移动距离，单位：米
    virtual void MoveLeft(float dist) = 0;
    // 上下移动（上移是正，下移是负）
    // .dist 移动距离，单位：米
    virtual void MoveUp(float dist) = 0;
    // 左右偏航（左偏是正，右偏是负）
    // .angle 角度
    virtual void YawLeft(float angle) = 0;
    // 原地左右旋转（左转是正，右转是负）
    virtual void RotateLeft(float angle) = 0;
    // 原地上下旋转（上是正，下是负）
    virtual void RotateUp(float angle) = 0;
    // 在摄像机观察平面上，上下左右移动（屏幕坐标系中，当前点与上一次的点偏移量）
    // .x,y 鼠标的移动偏移量
    virtual void PanelMove(LONG x, LONG y) = 0;
    // 在摄像机观察平面上，上下左右旋转（屏幕坐标系中，当前点与上一次的点偏移量）
    virtual void PanelRotate(LONG x, LONG y) = 0;

#if FUEL_OS_WINDOWS
    // 向摄像机投递窗口消息（此函数仅MFC时使用，使用WIN32时候，此函数会自动调用）
    virtual void OnMsgProc(UINT msg, WPARAM wparam, LPARAM lparam) = 0;
#endif
    // 重置摄像机到默认位置和状态
    virtual void ResetDefault() = 0;
};